﻿// ==================================================
// Copyright 2014 (C) , dotLogix
// Author: Alexander Schill <alexander@schillnet.de>.
// ==================================================

namespace DotLogix {
    #region Using Directives
    using System;
    using System.Windows;
    using System.Windows.Media;

    #endregion

    public abstract class AutoSizeBase : FrameworkElement {
        private ScaleTransform _transform;
        private Stretch _stretch = Stretch.Uniform;

        public AutoSizeBase() {
            VerticalAlignment = VerticalAlignment.Center;
            HorizontalAlignment = HorizontalAlignment.Center;
        }

        protected abstract Size Content { get; }

        public Stretch Stretch {
            get { return _stretch; }
            set {
                _stretch = value;
                InvalidateMeasure();
                InvalidateVisual();
            }
        }

        protected override Size MeasureOverride(Size availableSize) {
            double scaleX, scaleY;
            switch(Stretch) {
                case Stretch.None:
                    availableSize.Width = Content.Width;
                    availableSize.Height = Content.Height;
                    scaleX = 1;
                    scaleY = 1;
                    break;
                case Stretch.Fill:
                    scaleX = availableSize.Width / Content.Width;
                    scaleY = availableSize.Height / Content.Height;
                    break;
                case Stretch.Uniform:
                    scaleX =
                        scaleY = Math.Min(availableSize.Width / Content.Width, availableSize.Height / Content.Height);
                    availableSize.Width = Content.Width * scaleX;
                    availableSize.Height = Content.Height * scaleY;
                    break;
                case Stretch.UniformToFill:
                    scaleX =
                        scaleY = Math.Max(availableSize.Width / Content.Width, availableSize.Height / Content.Height);
                    availableSize.Width = Content.Width * scaleX;
                    availableSize.Height = Content.Height * scaleY;
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }
            if (double.IsInfinity(availableSize.Width) || double.IsNaN(availableSize.Width))
            {
                _transform = null;
                return Size.Empty;
            }
            if (double.IsInfinity(availableSize.Height) || double.IsNaN(availableSize.Height))
            {
                _transform = null;
                return Size.Empty;
            }
            _transform = new ScaleTransform(scaleX, scaleY);
            return availableSize;
        }

        protected override void OnRender(DrawingContext drawingContext) {
            drawingContext.PushTransform(_transform);
            RenderContent(drawingContext);
            drawingContext.Pop();
        }

        protected abstract void RenderContent(DrawingContext drawingContext);
    }
}